package ec.fugu.samples;

import com.roadtrack.view.components.AnimatedGIFField;
import com.roadtrack.vo.bussiness.UbikoConstants;

import net.rim.device.api.system.GIFEncodedImage;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.*;

/**
 * Wait for some Background processing to complete.
 * Meanwhile, display this popup screen and status updates as supplied.
 * Also allow the user to Cancel the Thread we are waiting on.
 */

public class PleaseWaitPopupScreen extends PopupScreen
                                   implements ObserverInterface {


    private GaugeField _gaugeField = null; // Indicator to user that things are happening
    private ButtonField _cancelButton = null; // Button user can use to get out
    private LabelField _statusText = null;

    private NetworkThread _requestThread = null;
    private String _requestURL = null;
    private int _returnCode = ObserverInterface.CANCELLED;
    private AnimatedGIFField _ourAnimation = null;

    public PleaseWaitPopupScreen(String title, String text, String requestURL) {
        super(new VerticalFieldManager());
        this.add(new LabelField(title, LabelField.FIELD_HCENTER));
        this.add(new SeparatorField());
        GIFEncodedImage ourAnimation = (GIFEncodedImage) GIFEncodedImage.getEncodedImageResource(UbikoConstants.loaderImage);
        _ourAnimation = new AnimatedGIFField(ourAnimation, Field.FIELD_HCENTER);
        this.add(_ourAnimation);
        this.add(new SeparatorField());
        this.add(new RichTextField(text, Field.READONLY));
        _gaugeField = new GaugeField(null, 1, 100, 1, GaugeField.NO_TEXT);
        this.add(_gaugeField);
        this.add(new SeparatorField());
        _cancelButton = new ButtonField("Cancel", ButtonField.FIELD_HCENTER | ButtonField.CONSUME_CLICK);
        _cancelButton.setChangeListener( new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
                if ( _requestThread != null ) {
                    if ( _requestThread.isAlive() ) {
                        _requestThread.stop();
                        // This will send us a 'failure' notification
                    }
                } else {
                    // Something has gone really wrong?!
                    throw new RuntimeException("Oppsss");
                }
            }
        });
        this.add(_cancelButton);
        _cancelButton.setFocus();
        _statusText = new LabelField("Starting");
        this.add(_statusText);
        _requestURL = requestURL;
    }

    public int show() {
        _requestThread = new NetworkThread(_requestURL, this);
        _requestThread.start();
        UiApplication.getUiApplication().pushModalScreen(this);
        return _returnCode;
    }


    /**
     * This method is called by the Background Thread
     * So we need to gain access to the Event Thread to update our Ui.
     */
    public void processStatusUpdate(final int status, final String statusString) {
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run () {
                _statusText.setText(statusString);
                if ( status > 0 ) {
                    _gaugeField.setValue(status);
                }
                PleaseWaitPopupScreen.this.invalidate();
            }
        });
    }

    /**
     * This method is called by the Background Thread
     * So we need to gain access to the Event Thread to update our Ui.
     */
    public void processResponse(final byte [] responseBytes) {
        _returnCode = ObserverInterface.OK;
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run () {
                Dialog.alert("Response:\n" + new String(responseBytes));
                UiApplication.getUiApplication().popScreen(PleaseWaitPopupScreen.this);
            }
        });
    }
            
    /**
     * This method is called by the Background Thread
     * So we need to gain access to the Event Thread to update our Ui.
     */
    public void processError(int errorCode, final String errorMessage) {
        _returnCode = errorCode;
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run () {
                Dialog.alert("Error:!\n" + errorMessage);
                UiApplication.getUiApplication().popScreen(PleaseWaitPopupScreen.this);
            }
        });
    }

}